#include "fleet.h"
#include "ship.h"
#include <algorithm>
#include "json/value.h"
#include <stdexcept>

using namespace std;

Fleet::Fleet(string _name) : CostKeeper(0) {
	name = _name;
	captain = "";
}

Fleet::Fleet(const Json::Value & _fleet, string _name) : CostKeeper(0), name(_name) {
	captain = _fleet["Captain"].asString();

	// TODO: Possibly check if ships are present and add them too.

	if ( _name == "" )
		name = _fleet["Name"].asString();
}

Json::Value Fleet::convertToJson(bool _shipsToo) const {
	Json::Value fleet;

	fleet["Name"] = name;
	fleet["Type"] = "Fleet";
	fleet["Captain"] = captain;
	fleet["Cost"] = getCost();

	if ( _shipsToo ) {
		int i = 0;
		for ( auto &it : ships ) {
			fleet["Ship"][i] = it->convertToJson();
			i++;
		}
	}

	return fleet;
}

void Fleet::addShip(Ship * _ship) {
	// Check that we don't have this ship already
	auto it = find(begin(ships), end(ships), _ship);
	if ( it == ships.end() ) {
		ships.push_back(_ship);
		_ship->registerObserver(this);
	}
}

void Fleet::rmShip(int _ship) {
	ships.at(_ship)->unregisterObserver(this); // This also checks that _ship is a valid index
	ships.erase(ships.begin() + _ship);
}

void Fleet::rmShip(Ship * _ship ) {
	auto it = find(ships.begin(), ships.end(), _ship);
	if ( it == ships.end() ) throw runtime_error("Fleet::rmShip(Ship*)");

	(*it)->unregisterObserver(this);
	ships.erase(it);
}

array<string,4> Fleet::getSummary() const {
	array<string,4> summary;

	summary[0] = name;
	summary[1] = captain;
	summary[2] = std::to_string(getShipsNumber());
	summary[3] = std::to_string(getCost());

	return summary;
}

vector<array<string,3>> Fleet::getShipSummaries() const {
	vector<array<string,3>> summaries;

	for ( auto & it : ships )
		summaries.push_back(it->getSummary());

	return summaries;
}
vector<string> Fleet::getShipNames() const {
	vector<string> names;

	for ( auto & it : ships )
		names.push_back(it->name);

	return names;
}

const Ship* Fleet::getShip(int _ship) const		{return ships.at(_ship);}
int Fleet::getShipsNumber() const				{return ships.size();}

